/*
 * Matrix2x3.cpp
 *
 *  Created on: 2011/06/24
 *      Author: naoki
 */

#include "NTEngine/NTEngine.h"
#include "NTEngine/Math/Function.h"
#include "NTEngine/Math/Vector2.h"
#include "NTEngine/Math/Matrix2x3.h"

namespace NTEngine {
namespace Math {

Matrix2x3::Matrix2x3( const Matrix2x3 & a )
: m11( a.m11 ), m12( a.m12 ), m13( a.m13 )
, m21( a.m21 ), m22( a.m22 ), m23( a.m23 )
{
}

void Matrix2x3::operator =( const Matrix2x3& a ) {
	m11 = a.m11;
	m12 = a.m12;
	m13 = a.m13;
	m21 = a.m21;
	m22 = a.m22;
	m23 = a.m23;
}

void Matrix2x3::operator *=( const Matrix2x3& a ) {
	float tX, tY;

	tX = m11;
	tY = m12;
	m11 = tX * a.m11 + tY * a.m21;
	m12 = tX * a.m12 + tY * a.m22;
	m13 = tX * a.m13 + tY * a.m23 + a.m13;

	tX = m21;
	tY = m22;
	m21 = tX * a.m11 + tY * a.m21;
	m22 = tX * a.m12 + tY * a.m22;
	m23 = tX * a.m13 + tY * a.m23 + a.m23;
}

void Matrix2x3::setTranslation( const Vector2& a ) {
	m11 = m22 = 1.F;
	m12 = m21 = 0.F;
	m13 = a.x;
	m23 = a.y;
}

void Matrix2x3::setRotation( float a ) {
	float c = cos( a );
	float s = sin( a );
	m11 = c;
	m22 = c;
	m12 = -s;
	m21 = s;
	m13 = m23 = 0.F;
}

void Matrix2x3::setScaling( const Vector2& a ) {
	m11 = a.x;
	m22 = a.y;
	m12 = m13 = m21 = m23 = 0.F;
}

void Matrix2x3::multiply( const Vector2& a, Vector2* out ) const {
	float tX = a.x;
	out->x = m11 * tX + m12 * a.y + m13;
	out->y = m21 * tX + m22 * a.y + m23;
}

void Matrix2x3::translate( const Vector2& a ) {
// { m11  m12  m13 }   { 1  0  a.x }   { m11  m12  m11*a.x+m12*a.y+m13 }
// { m21  m22  m23 } * { 0  1  a.y } = { m21  m22  m21*a.x+m22*a.y+m23 }
// {   0    0    1 }   { 0  0    1 }   {   0    0                    1 }
	m13 = m11 * a.x + m12 * a.y + m13;
	m23 = m21 * a.x + m22 * a.y + m23;
}

void Matrix2x3::rotate( float a ) {
// { m11  m12  m13 }   { c -s  0 }   { m11*c+m12*s  m12*c-m11*s  m13 }
// { m21  m22  m23 } * { s  c  0 } = { m21*c+m22*s  m22*c-m21*s  m23 }
// {   0    0    1 }   { 0  0  1 }   {           0            0    1 }
	float c = cos( a );
	float s = sin( a );
	float t; // 書き換え対策用
	t = m11;
	m11 = t * c + m12 * s;
	m12 = m12 * c - t * s;
	t = m21;
	m21 = t * c + m22 * s;
	m22 = m22 * c - t * s;
}

void Matrix2x3::scale( const Vector2& a ) {
// { m11  m12  m13 }   { a.x    0  0 }   { m11*a.x  m12*a.y  m13 }
// { m21  m22  m23 } * {   0  a.y  0 } = { m21*a.x  m22*a.y  m23 }
// {   0    0    1 }   {   0    0  1 }   {       0        0    1 }
	m11 *= a.x;
	m12 *= a.y;
	m21 *= a.x;
	m22 *= a.y;
}

} // namespace Math
} // namespace NTEngine
